package cn.yoshii.ad.adserver

import cn.yoshii.ad.adserver.chang.ChangAdService
import cn.yoshii.ad.adserver.model.entity.AdInfo
import cn.yoshii.ad.adserver.model.entity.AdInfoRepository
import cn.yoshii.ad.adserver.model.entity.Report
import cn.yoshii.ad.adserver.model.entity.ReportRepository
import cn.yoshii.ad.adserver.param.CallbackRequest
import cn.yoshii.ad.adserver.param.DeviceRequest
import cn.yoshii.ad.adserver.param.ReportRequest
import cn.yoshii.ad.adserver.util.ONE_DAY_MILLISECONDS
import cn.yoshii.libs.webstarter.exception.MyException
import cn.yoshii.libs.webstarter.util.Log
import cn.yoshii.libs.webstarter.util.MD5Util
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.repository.findByIdOrNull
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author xiang
 * @Date 2024/2/15 20:20
 **/
@Service
class AdService {

    companion object {
        private const val TAG = "AdService"
    }

    @Autowired
    private lateinit var changAdService: ChangAdService

    @Autowired
    private lateinit var adInfoRepository: AdInfoRepository

    @Autowired
    private lateinit var reportRepository: ReportRepository

    fun getAds(request: DeviceRequest): List<AdInfo> {
        Log.i(TAG, "request: $request")
        return changAdService.getAds(request)
    }

    @Transactional
    fun updateAd(adInfo: AdInfo) {
        adInfoRepository.save(adInfo)
    }

    @Transactional
    fun report(request: ReportRequest): String {

        Log.i(TAG, "request: $request")

        val info = adInfoRepository.findByIdOrNull(
            request.adId
        ) ?: throw MyException(NO_AD_INFO)

        val requestId = MD5Util.random32()
        changAdService.report(request, info.packId, requestId)

        reportRepository.save(
            Report(
                id = 0,
                adId = info.id,
                reportTime = System.currentTimeMillis(),
                activeTime = 0,
                requestId = requestId,
                active = false
            )
        )

        return requestId
    }

    @Transactional
    fun callback(request: CallbackRequest) {
        val report = reportRepository.findByRequestId(
            request.requestId
        ) ?: return
        report.active = true
        report.activeTime = System.currentTimeMillis()
    }

    fun isActive(requestId: String): Boolean {
        val report = reportRepository.findByRequestId(requestId) ?: return false
        return report.active
    }

    /**
     * 定时清理广点通上报缓存信息
     */
    @Scheduled(cron = "0 0 3 * * ?")
    @Transactional
    fun clearReport() {
        Log.i(TAG, "clearReport")
        // 清理 5 天前的信息
        reportRepository.deleteByReportTimeLessThan(
            System.currentTimeMillis() - ONE_DAY_MILLISECONDS * 5
        )
    }
}